home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The PC-SIG Library 9
/
The PC-SIG Library on CD ROM - Ninth Edition.iso
/
401_500
/
DISK0417
/
DISK0417.ZIP
/
PROLOG.ARC
/
VISION.ARC
/
FRAMES.PRO
next >
Wrap
Text File
|
1986-05-26
|
6KB
|
220 lines
.he FRAMES.PRO
.pn1
/*
Title: Frames.pro
Function: Module 1/3 of Frames System
*/
/* get the Value of Slot in a given Frame */
frame_get(Frame,Slot,Value) :-
ffget(Frame,Frame,Slot,Value).
ffget(Parameter_Frame,Frame,Slot,Value) :- /* check for a value Facet */
fget(Frame,Slot,value,Value).
ffget(Parameter_Frame,Frame,Slot,Value) :- /* does it have a default? */
fget(Frame,Slot,default,Value).
ffget(Parameter_Frame,Frame,Slot,Value) :- /* how about a demon? */
fget(Frame,Slot,if_needed,Rule),
F =.. [Rule,Parameter_Frame,Value],
F.
ffget(Parameter_Frame,Frame,Slot,Value) :- /* none of the above */
fget(Frame,ako,value,Parent), /* so, move up the hierarchy */
ffget(Parameter_Frame,Parent,Slot,Value).
fget(Frame,Slot,Facet,Value) :- /* just grab the given Facet or fail */
F =.. [Frame,Slot,Facet,Value],
F.
/* put Value in Slot of a given Frame. If this Slot has an associated
if_added demon, then grab it and execute it after installing the
given Value.
*/
frame_put(Frame,Slot,Value) :-
get_rule(Frame,Slot,if_added,Rule), /* must we do something extra */
fput(Frame,Slot,value,Value),
F =.. [Rule,Frame,Value],
F.
frame_put(Frame,Slot,Value) :-
fput(Frame,Slot,value,Value). /* just a simple fput will do */
fput(Frame,Slot,Facet,Value) :-
F =.. [Frame,Slot,Facet,Value],
assertz(F).
/* remove Slot from a given Frame. If the Slot has an associated
if_removed demon, then grab the rule and execute it before ,
removing the Slot.
*/
frame_remove(Frame,Slot) :-
get_rule(Frame,Slot,if_removed,Rule), /* something extra to do */
F =.. [Rule,Frame],
F,
fremove(Frame,Slot).
frame_remove(Frame,Slot) :-
fremove(Frame,Slot). /* just a simple fremove */
fremove(Frame,Slot) :-
F =.. [Frame,Slot,value,Value],
retract(F).
fremove(_,_). /* if Slot doesn't exist, then no harm done */
/* replace whatever is in Slot with Value. If the Slot has an associated
if_replaced rule, then grab it and execute it after doing the
replacement.
*/
frame_replace(Frame,Slot,Value) :-
get_rule(Frame,Slot,if_replaced,Rule), /* something extra to do */
freplace(Frame,Slot,Value),
F =.. [Rule,Frame],
F.
frame_replace(Frame,Slot,Value) :-
freplace(Frame,Slot,Value). /* just a simple replace */
freplace(Frame,Slot,Value) :-
fremove(Frame,Slot),
frame_put(Frame,Slot,Value).
/* append Value to the list in Slot. If Slot has an associated
if_appended rule, then grab it and execute it after appending
the Value.
*/
frame_append(Frame,Slot,Value) :-
get_rule(Frame,Slot,if_appended,Rule),
fappend(Frame,Slot,Value),
F =.. [Rule,Frame],
F.
frame_append(Frame,Slot,Value) :-
fappend(Frame,Slot,Value).
/* here we check to see if the slot already exists.
If it does, then we just append the new Value to the old value list.
If the Slot does not exist, then we create it and give it a value
consisting of the list whose single element is Value.
*/
fappend(Frame,Slot,Value) :-
fget(Frame,Slot,value,Old),
(member(Value,Old)
;
fremove(Frame,Slot),
fput(Frame,Slot,value,[Value|Old])
).
fappend(Frame,Slot,Value) :-
fput(Frame,Slot,value,[Value]).
/* this is a simple utility predicate used to travel up the frame
hierarchy looking for an appropriate rule to grab.
*/
get_rule(Frame,Slot,Type,Rule) :-
fget(Frame,Slot,Type,Rule).
get_rule(Frame,Slot,Type,Rule) :-
fget(Frame,ako,value,Parent),
get_rule(Parent,Slot,Type,Rule).
/* Example
frame representation:
cylinder
ako
value : thing
height
if_added : cylinder_height_add
if_removed : cylinder_height_remove
radius
if_added : cylinder_radius_add
If_removed : cylinder_radius_remove
cross_section
if_needed : cylinder_cross_section
volume
if_needed : cylinder_volume
cylinder1
ako
value : cylinder
comments: cylinder1 above is an instance of cylinder. When we
use frame_put(cylinder1,radius,2), say, the system will install
the number "2" as the value of cylinder1's radius and it will
further compute cylinder1's cross sectional area and install it
under the cross_section slot. Similar actions take place when we
do a frame_put for cylinder1's height. Below is the Prolog code
that implements all this. NOTE: PDPROLOG only supports integer
arithmetic.
*/
cylinder(ako,value,geometric_object).
cylinder(height,if_added,cylinder_height_add).
cylinder(height,if_removed,cylinder_height_remove).
cylinder(radius,if_added,cylinder_radius_add).
cylinder(radius,if_removed,cylinder_radius_remove).
cylinder(cross_section,if_needed,cylinder_cross_section).
cylinder(volume,if_needed,cylinder_volume).
/* if we get the height, then we try to compute the cylinder's
volume.
*/
cylinder_height_add(Cylinder,_) :-
cylinder_volume(Cylinder,_).
cylinder_height_add(_,_). /* if we can't do it,
e.g., the radius is unknown,
then no harm done */
/* if the height is removed, then the old volume is no
longer valid
*/
cylinder_height_remove(Cylinder) :-
frame_remove(Cylinder,volume).
/* if we get the radius, then we can compute the cylinder's
cross sectional area
*/
cylinder_radius_add(Cylinder,_) :-
cylinder_cross_section(Cylinder,_).
/* if the radius is removed, then the old cross sectional area
is no longer valid
*/
cylinder_radius_remove(Cylinder) :-
frame_remove(Cylinder,cross_section),
frame_remove(cylinder,volume).
/* PDPROLOG does not support floating-point arithmetic, so pi has been
approximated as 3. If you are using a commercial prolog, change 3 to 3.1416
*/
cylinder_cross_section(Cylinder,Cross_Section) :-
frame_get(Cylinder,radius,Radius),
Cross_Section is 3*Radius*Radius,
freplace(Cylinder,cross_section,Cross_Section).
cylinder_volume(Cylinder,Volume) :-
frame_get(Cylinder,cross_section,Cross_Section),
frame_get(Cylinder,height,Height),
Volume is Height*Cross_Section,
freplace(Cylinder,volume,Volume).
cylinder1(ako,value,cylinder).